<?php
/**
 * Created by PhpStorm.
 * User: u
 * Date: 2018/12/18
 * Time: 15:34
 */

namespace common\services\kq;

use common\widgets\Request;
use common\widgets\Tool;
use Yii;
class KqPayService
{
    private $config = [];
    public function __construct()
    {
        $this->config = require 'kq-config.php';
        require 'log.php';
    }

    //获取支付宝和支付跳转
    public function pay($data)
    {
        $config = $this->config;
        $arr =$config['qk_config_rmb'];

        if(!empty($data['order_amount'])){
            $arr['orderAmount'] = $data['order_amount']*100;
        }
        if($data['pay_type'] == 1){
            $arr['payType'] = '28-1';
            $arr['ext2'] = 1;
        }else if($data['pay_type'] == 2){
            $arr['payType'] = '28-2';
            $arr['ext2'] = 2;
        }
        if(!empty($data['shop_name']))
        {
            $arr['ext2'] = $data['shop_name'];
            $arr['bgUrl'] = Yii::$app->params['kq_pay_notify_url']."/kq/notify";
        }

        $arr['orderTime'] = Date("YmdHis");
        $arr['orderId'] = "ZJTS".time().str_pad(mt_rand(1,9999),4,0,STR_PAD_LEFT);
        $arr['ext1'] = $data['bus_id'];
        $url = Yii::$app->params['kq_pay_url'];
        $signMsg = $this->getSignMsg($arr);
        $arr['signMsg'] = $signMsg;
        $xmls = $this->http_request($url,$arr);
        $zArr = $this->getXmlUrl($xmls);
        $pay_urls = '';
        if($data['pay_type'] == 1){
            $pay_urls = $zArr['wechatQrcode'];
        }else if($data['pay_type'] == 2){
            $pay_urls = $zArr['alipayQrcode'];
        }
        return array(
            'pay_url'=> $pay_urls,
            'orderId' => $arr['orderId'],
        );
    }
    public function payBank($data)
    {
        $config = $this->config;
        $arr =$config['qk_config_rmb'];

        if(!empty($data['order_amount'])){
            $arr['orderAmount'] = $data['order_amount']*100;
        }
        $arr['orderTime'] = Date("YmdHis");
//        $arr['orderId'] = "CJW".time().str_pad(mt_rand(1,9999),4,0,STR_PAD_LEFT);
        $arr['orderId'] = $data['orderId'];
        if($data['pay_type'] == 1){
            $arr['payType'] = '28-1';
        }else if($data['pay_type'] == 2){
            $arr['payType'] = '28-2';
        }else if($data['pay_type'] ==3)
        {
            $arr['payType'] = 10;
            $arr['ext2'] = 3;
            if($data['bank_id'] ==1 )
            {
                $arr['bankId'] = 'ICBC';
            }else if($data['bank_id'] ==2)
            {
                $arr['bankId'] = 'CCB';
            }else if($data['bank_id'] == 3)
            {
                $arr['bankId'] = 'ABC';
            }else if($data['bank_id'] ==4)
            {
                $arr['bankId'] = 'BOC';
            }else{
                $arr['bankId'] = '';
            }
        }
        if(!empty($data['shop_name']))
        {
            $arr['ext2'] = $data['shop_name'];
            $arr['bgUrl'] = Yii::$app->params['kq_pay_notify_url']."/kq/notify";
        }
        $arr['ext1'] = $data['bus_id'];
        $url = Yii::$app->params['kq_pay_url'];
        $signMsg = $this->getSignMsg($arr);
        $arr['signMsg'] = $signMsg;
        $request = http_build_query($arr);
        header("Location:".$url."?".$request);
    }

    public function doNotify($data)
    {
        $config = $this->config;
        $nrr =$config['qk_config_rmb'];
        $logHandler= new CLogFileHandler(dirname(__FILE__)."/logs/".date('Y-m-d').'.log');
        $log = Log::Init($logHandler, 15);
        Log::DEBUG("query:" . json_encode($_REQUEST));

        //人民币网关账号，该账号为11位人民币网关商户编号+01,该值与提交时相同。
        $kq_check_all_para = $this->kq_ck_null($_REQUEST['merchantAcctId'],'merchantAcctId');
        //网关版本，固定值：v2.0,该值与提交时相同。
        $kq_check_all_para .= $this->kq_ck_null($_REQUEST['version'],'version');
        //语言种类，1代表中文显示，2代表英文显示。默认为1,该值与提交时相同。
        $kq_check_all_para .= $this->kq_ck_null($_REQUEST['language'],'language');
        //签名类型,该值为4，代表PKI加密方式,该值与提交时相同。
        $kq_check_all_para.= $this->kq_ck_null($_REQUEST['signType'],'signType');
        //支付方式，一般为00，代表所有的支付方式。如果是银行直连商户，该值为10,该值与提交时相同。
        $kq_check_all_para .= $this->kq_ck_null($_REQUEST['payType'],'payType');
        //银行代码，如果payType为00，该值为空；如果payType为10,该值与提交时相同。
        $kq_check_all_para .= $this->kq_ck_null($_REQUEST['bankId'],'bankId');
        //商户订单号，,该值与提交时相同。
        $kq_check_all_para .= $this->kq_ck_null($_REQUEST['orderId'],'orderId');
        //订单提交时间，格式：yyyyMMddHHmmss，如：20071117020101,该值与提交时相同。
        $kq_check_all_para.= $this->kq_ck_null($_REQUEST['orderTime'],'orderTime');
        //订单金额，金额以“分”为单位，商户测试以1分测试即可，切勿以大金额测试,该值与支付时相同。
        $kq_check_all_para .= $this->kq_ck_null($_REQUEST['orderAmount'],'orderAmount');
        // 快钱交易号，商户每一笔交易都会在快钱生成一个交易号。
        $kq_check_all_para .= $this->kq_ck_null($_REQUEST['dealId'],'dealId');
        //银行交易号 ，快钱交易在银行支付时对应的交易号，如果不是通过银行卡支付，则为空
        $kq_check_all_para.= $this->kq_ck_null($_REQUEST['bankDealId'],'bankDealId');
        //快钱交易时间，快钱对交易进行处理的时间,格式：yyyyMMddHHmmss，如：20071117020101
        $kq_check_all_para .= $this->kq_ck_null($_REQUEST['dealTime'],'dealTime');
        //商户实际支付金额 以分为单位。比方10元，提交时金额应为1000。该金额代表商户快钱账户最终收到的金额。
        $kq_check_all_para .= $this->kq_ck_null($_REQUEST['payAmount'],'payAmount');
        //费用，快钱收取商户的手续费，单位为分。
        $kq_check_all_para .= $this->kq_ck_null($_REQUEST['fee'],'fee');
        //扩展字段1，该值与提交时相同
        $kq_check_all_para .= $this->kq_ck_null($_REQUEST['ext1'],'ext1');
        //扩展字段2，该值与提交时相同。
        $kq_check_all_para .= $this->kq_ck_null($_REQUEST['ext2'],'ext2');
        //处理结果， 10支付成功，11 支付失败，00订单申请成功，01 订单申请失败
        $kq_check_all_para .= $this->kq_ck_null($_REQUEST['payResult'],'payResult');
        //错误代码 ，请参照《人民币网关接口文档》最后部分的详细解释。
        $kq_check_all_para .= $this->kq_ck_null($_REQUEST['errCode'],'errCode');

        $trans_body=substr($kq_check_all_para,0,strlen($kq_check_all_para)-1);
        $MAC=base64_decode($_REQUEST['signMsg']);
        $fp = fopen(dirname(__FILE__)."/files/99bill.cert.rsa.20340630.cer", "r");
        $cert = fread($fp, 8192);
        fclose($fp);
        $pubkeyid = openssl_get_publickey($cert);
        $ok = openssl_verify($trans_body, $MAC, $pubkeyid);
        if ($ok == 1) {
            switch($_REQUEST['payResult']){
                case '10':
                    //此处做商户逻辑处理
                    $rtnOK=1;
                    //以下是我们快钱设置的show页面，商户需要自己定义该页面。
                    $rtnUrl = $nrr['pageUrl']."?msg=success";
                    Log::DEBUG("success:" . json_encode($_REQUEST));
                    break;
                default:
                    $rtnOK=0;
                    //以下是我们快钱设置的show页面，商户需要自己定义该页面。
                    $rtnUrl = $nrr['pageUrl']."?msg=false";
                    Log::DEBUG("false:" . json_encode($_REQUEST));
                    break;

            }

        }else{
            $rtnOK=0;
            //以下是我们快钱设置的show页面，商户需要自己定义该页面。
            $rtnUrl = $nrr['pageUrl']."?msg=error";
            Log::DEBUG("error:" . json_encode($_REQUEST));
            Log::DEBUG("result:".$ok);
        }
        $str = "<result>".$rtnOK."</result> <redirecturl>".$rtnUrl."</redirecturl>";
        return array(
            'rtnOK' => $rtnOK,
            'orderId' => $_REQUEST['orderId'],
            'str' => $str,
        );

    }
    //生成签名
    private function getSignMsg($arr){
        $merchantAcctId = $arr['merchantAcctId'];
        $inputCharset = $arr['inputCharset'];
        $pageUrl = $arr['pageUrl'];
        $bgUrl = $arr['bgUrl'];
        $version = $arr['version'];
        $language = $arr['language'];
        $signType = $arr['signType'];
        $payerName = $arr['payerName'];
        $payerContactType = $arr['payerContactType'];
        $payerContact = $arr['payerContact'];
        $orderId = $arr['orderId'];
        $orderAmount = $arr['orderAmount'];
        $orderTime = $arr['orderTime'];
        $productName = $arr['productName'];
        $productNum = $arr['productNum'];
        $productId = $arr['productId'];
        $productDesc = $arr['productDesc'];
        $ext1 = $arr['ext1'];
        $ext2 = $arr['ext2'];
        $payType = $arr['payType'];
        $bankId = $arr['bankId'];
        $redoFlag = $arr['redoFlag'];
        $pid = $arr['pid'];
        $payerIdType = $arr['payerIdType'];
        $payerId = $arr['payerId'];

        $kq_all_para = $this->kq_ck_null($inputCharset,'inputCharset');
        $kq_all_para .= $this->kq_ck_null($pageUrl,"pageUrl");
        $kq_all_para .= $this->kq_ck_null($bgUrl,'bgUrl');
        $kq_all_para .= $this->kq_ck_null($version,'version');
        $kq_all_para .= $this->kq_ck_null($language,'language');
        $kq_all_para .= $this->kq_ck_null($signType,'signType');
        $kq_all_para .= $this->kq_ck_null($merchantAcctId,'merchantAcctId');
        $kq_all_para .= $this->kq_ck_null($payerName,'payerName');
        $kq_all_para .= $this->kq_ck_null($payerContactType,'payerContactType');
        $kq_all_para .= $this->kq_ck_null($payerContact,'payerContact');
        $kq_all_para .= $this->kq_ck_null($payerIdType,'payerIdType');
        $kq_all_para .= $this->kq_ck_null($payerId,'payerId');
        $kq_all_para .= $this->kq_ck_null($orderId,'orderId');
        $kq_all_para .= $this->kq_ck_null($orderAmount,'orderAmount');
        $kq_all_para .= $this->kq_ck_null($orderTime,'orderTime');
        $kq_all_para .= $this->kq_ck_null($productName,'productName');
        $kq_all_para .= $this->kq_ck_null($productNum,'productNum');
        $kq_all_para .= $this->kq_ck_null($productId,'productId');
        $kq_all_para .= $this->kq_ck_null($productDesc,'productDesc');
        $kq_all_para .= $this->kq_ck_null($ext1,'ext1');
        $kq_all_para .= $this->kq_ck_null($ext2,'ext2');
        $kq_all_para .= $this->kq_ck_null($payType,'payType');
        $kq_all_para .= $this->kq_ck_null($bankId,'bankId');
        $kq_all_para .= $this->kq_ck_null($redoFlag,'redoFlag');
        $kq_all_para .= $this->kq_ck_null($pid,'pid');

        $kq_all_para=substr($kq_all_para,0,strlen($kq_all_para)-1);

        /////////////  RSA 签名计算 ///////// 开始 //
        $fp = fopen(dirname(__FILE__)."/files/99bill-rsa.pem", "r");
        $priv_key = fread($fp, 123456);
        fclose($fp);
        $pkeyid = openssl_get_privatekey($priv_key);

        // compute signature
        openssl_sign($kq_all_para, $signMsg, $pkeyid,OPENSSL_ALGO_SHA1);
        // free the key from memory
        openssl_free_key($pkeyid);
        $signMsg = base64_encode($signMsg);
        /////////////  RSA 签名计算 ///////// 结束 //
        return $signMsg;
    }

    //xml_url
    private function getXmlUrl($xmls){
        $xml = simplexml_load_string($xmls);
        $xmljson= json_encode($xml);
        $xml=json_decode($xmljson,true);
        return $xml;
    }
    private function http_request($url,$data = null){
        $postdata = http_build_query($data);
        $opts = array('http' =>
            array( 'method'  => 'POST','header'  => 'Content-type: application/x-www-form-urlencoded', 'content' => $postdata )
        );
        $context = stream_context_create($opts);
        $result = file_get_contents($url, false, $context);
        return $result;
    }
    //
    private function kq_ck_null($kq_va,$kq_na){
        if($kq_va == ""){
            $kq_va = "";
        }else{
            return $kq_va=$kq_na.'='.$kq_va.'&';
        }
    }
}